package com.yzy.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yzy.common.Code;
import com.yzy.controller.dto.HandPaperDTO;
import com.yzy.entity.PQ;
import com.yzy.entity.Paper;
import com.yzy.entity.Question;
import com.yzy.exception.ServiceException;
import com.yzy.mapper.PaperMapper;
import com.yzy.service.IPQService;
import com.yzy.service.IPaperService;
import com.yzy.service.IQuestionService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * PaperServiceImpl
 *
 * @author 杨子宇
 * @createTime 2023-04-21
 */
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements IPaperService {
    @Resource
    private IQuestionService questionService;

    @Resource
    private IPQService paperQuestionService;

    public List<Paper> findAll() {
        return list();
    }

    public Paper findById(Integer id) {
        return getById(id);
    }

    public Paper insertOrUpdate(Paper paper) {
        saveOrUpdate(paper);
        return paper;
    }

    public boolean deleteById(Integer id) {
        return removeById(id);
    }

    public boolean deletePapers(List<Integer> ids) {
        return removeByIds(ids);
    }

    public Page<Paper> findPage(Integer pageNum, Integer pageSize,String paperName) {
        Page<Paper> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Paper> queryWrapper = new QueryWrapper<>();
        if (!"".equals(paperName)) {
            queryWrapper.or().like("name", paperName);
        }
        return page(page, queryWrapper);
    }

    public Paper takePaper(Paper paper) {
        // 删除旧的试卷
        UpdateWrapper<PQ> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("paper_id", paper.getPaperId());
        paperQuestionService.remove(updateWrapper);

        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", paper.getCourseId());

        // 根据课程id查询出所以该课程的题目，在根据type划分
        List<Question> questionList = questionService.list(queryWrapper);
        // 选择题数量
        List<Question> type1List = questionList.stream().filter(question -> question.getType() == 1).collect(Collectors.toList());
        // 判断题数量
        List<Question> type2List = questionList.stream().filter(question -> question.getType() == 2).collect(Collectors.toList());
        // 问答题数量
        List<Question> type3List = questionList.stream().filter(question -> question.getType() == 3).collect(Collectors.toList());

        if (type1List.size() < paper.getType1()) {
            throw new ServiceException(Code.code_401, "选择题 在题库中数量不足");
        }
        if (type2List.size() < paper.getType2()) {
            throw new ServiceException(Code.code_401, "判断题 在题库中数量不足");
        }
        if (type3List.size() < paper.getType3()) {
            throw new ServiceException(Code.code_401, "问答题 在题库中数量不足");
        }

        // 开始随机组卷
        List<PQ> paperQuestion = getPaperQuestion(type1List.size(), paper.getType1(), type1List, paper.getPaperId());
        paperQuestion.addAll(getPaperQuestion(type2List.size(), paper.getType2(), type2List, paper.getPaperId()));
        paperQuestion.addAll(getPaperQuestion(type3List.size(), paper.getType3(), type3List, paper.getPaperId()));

        paperQuestionService.saveBatch(paperQuestion);

        return paper;
    }

    /**
     * 封装获取试卷和题目关联关系的方法
     */
    private List<PQ> getPaperQuestion(int questionSize, int paperQuestionSize, List<Question> source, Integer paperId) {
        List<Integer> typeRandomList = getEleList(questionSize, paperQuestionSize);
        List<PQ> list = new ArrayList<>();
        for (Integer index : typeRandomList) {
            Question question = source.get(index);
            PQ pq = new PQ();
            pq.setPaperId(paperId);
            pq.setQuestionId(question.getId());
            list.add(pq);
        }

        return list;
    }

    /**
     * 封装获取随机数方法
     */
    private List<Integer> getEleList(int sourceSize, int resultSize) {

        List<Integer> list = CollUtil.newArrayList();
        for (int i = 0; i < sourceSize; i++) {
            list.add(i);
        }
        return RandomUtil.randomEleList(list, resultSize);
    }

    public List<Question> paperView(Integer paperId) {
        List<Question> list = paperQuestionService.selectQuestions(paperId);
        return list;
    }

    public HandPaperDTO handPaper(HandPaperDTO handPaperDTO) {
        // 删除旧的试卷
        UpdateWrapper<PQ> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("paper_id", handPaperDTO.getPaperId());
        paperQuestionService.remove(updateWrapper);

        if (CollUtil.isEmpty(handPaperDTO.getHandleQuestionIds())) {
            throw new ServiceException(Code.code_401, "题目数量不足");
        }

        List<Integer> handleQuestionIds = handPaperDTO.getHandleQuestionIds();
        List<PQ> list = new ArrayList<>();
        for (Integer handleQuestionId : handleQuestionIds) {
            PQ paperQuestion = new PQ();
            paperQuestion.setPaperId(handPaperDTO.getPaperId());
            paperQuestion.setQuestionId(handleQuestionId);
            list.add(paperQuestion);
        }

        paperQuestionService.saveBatch(list);
        return handPaperDTO;
    }
}

